#include "Tween.hpp"

std::vector<Tween*> Tween::s_tweens;
std::vector<Tween*> Tween::s_inactiveTweens;

Tween::Tween()
	: m_active(false),
	m_elapsedTime(0)
{
}

Tween* Tween::Create(float* target, float from, float to, float duration)
{
	Tween* tween;
	if (s_inactiveTweens.size() > 0)
	{
		tween = s_inactiveTweens.back();
		s_inactiveTweens.pop_back();
	}
	else
	{
		s_tweens.push_back(new Tween());
		tween = s_tweens.back();
	}

	tween->m_target = target;
	tween->m_active = true;
	tween->m_elapsedTime = 0;
	tween->startValue = from;
	tween->endValue = to;
	tween->duration = duration;

	return tween;
}

void Tween::UpdateAll(float dt)
{
	for (auto it = s_tweens.begin(); it != s_tweens.end(); ++it)
	{
		(*it)->Update(dt);
	}
}

void Tween::Update(float dt)
{
	if (!m_active)
		return;

	m_elapsedTime += dt;
	float elapsedRatio = m_elapsedTime / duration;
	float distance = endValue - startValue;
	*m_target = startValue + distance * elapsedRatio;
	
	if (m_elapsedTime >= duration)
	{
		// TODO: Make users explicitly add tween to inactive queue to avoid errors if they hold a reference
		m_active = false;
		s_inactiveTweens.push_back(this);
		*m_target = endValue;
	}
}